extern int main();
extern void SystemInit();
extern void __libc_init_array();
/*
naked 属性 告诉编译器 不生成 压栈汇编 push {r7, lr}等指令

ARM 状态与 Thumb 状态
有些处理器同时支持 ARM 和 Thumb 指令集,通过 BX 或 BLX 指令进行切换,当指令 BX
跳转地址的 LSB 位为 1,表示切换到 Thumb 状态,为 0 则切换到 ARM 状态。

无论是 ARM 还是
Thumb,其指令在存储器中都是边界对齐的（2字节或4字节对齐）,也就是地址的最低位总是
0。 因此,在执行跳转过程中,PC 寄存器中的最低位被舍弃,不起作用。 在 BX
指令的执行过程中,最低位正好被用作状态判断的标志,不会造成存储器访问不对齐的错误。

Cortex-M 系列处理器不支持 ARM 指令,因此也不存在 ARM
状态,所以反汇编中的函数地址最低位都是 1

bin 部分数据含义
0x8000000-0x8000003  ：中断向量表定义 栈顶指针,SRAM最大地址  送  SP
0x8000004-0x8000008  : 存储 reset中断函数地址（_start_func） 送  PC
 */

// reset handle

__attribute__((naked)) void _start_func()
{
	extern unsigned int _sidata, _sdata, _edata, _sbss, _ebss;

	unsigned int *sdata        ;  // 0x20000000
	unsigned int *data_atflash ;  // 0x80000xx

	// copy data from flash to sram
	sdata = &_sdata;         // 0x20000000
	data_atflash = &_sidata; // 0x80000xx
	while (sdata < &_edata)
	{
		*sdata++ = *data_atflash++;
	}

	/*clear bss*/
	sdata = &_sbss;
	while (sdata < &_ebss)
	{
		*sdata++ = 0;
	}
	// SystemInit();
	__libc_init_array();
	main();
}

/***********************中断向量声明******************************* */
//  声明 中断函数 防止编译器报错
#ifndef __WEAK
#define __WEAK __attribute__((weak))
#endif

__WEAK void NMI_Handler()
{
	for (;;)
	{
	}
}

__WEAK void HardFault_Handler()
{
	for (;;)
	{
	}
}

__WEAK void SVC_Handler() {}

__WEAK void PendSV_Handler() {}
__WEAK void SysTick_Handler() {}

__WEAK void WWDGT_IRQHandler() {}	 /* 16:Window Watchdog Timer */
__WEAK void LVD_IRQHandler() {}		 /* 17:LVD through EXTI Line detect */
__WEAK void RTC_IRQHandler() {}		 /* 18:RTC through EXTI Line */
__WEAK void FMC_IRQHandler() {}		 /* 19:FMC */
__WEAK void RCU_IRQHandler() {}		 /* 20:RCU */
__WEAK void EXTI0_1_IRQHandler() {}	 /* 21:EXTI Line 0 and EXTI Line 1 */
__WEAK void EXTI2_3_IRQHandler() {}	 /* 22:EXTI Line 2 and EXTI Line 3 */
__WEAK void EXTI4_15_IRQHandler() {} /* 23:EXTI Line 4 to EXTI Line 15 */

__WEAK void DMA_Channel0_IRQHandler() {}		  /* 25:DMA Channel 0 */
__WEAK void DMA_Channel1_2_IRQHandler() {}		  /* 26:DMA Channel 1 and DMA Channel 2 */
__WEAK void DMA_Channel3_4_IRQHandler() {}		  /* 27:DMA Channel 3 and DMA Channel 4 */
__WEAK void ADC_CMP_IRQHandler() {}				  /* 28:ADC and Comparator */
__WEAK void TIMER0_BRK_UP_TRG_COM_IRQHandler() {} /* 29:TIMER0 Break,Update,Trigger and Commutation */
__WEAK void TIMER0_Channel_IRQHandler() {}		  /* 30:TIMER0 Channel Capture Compare */

__WEAK void TIMER2_IRQHandler() {} /* 32:TIMER2 */
__WEAK void TIMER5_IRQHandler() {} /* 33:TIMER5 */

__WEAK void TIMER13_IRQHandler() {} /* 35:TIMER13 */

__WEAK void TIMER14_IRQHandler() {} /* 36:TIMER14 */
__WEAK void TIMER15_IRQHandler() {} /* 37:TIMER15 */
__WEAK void TIMER16_IRQHandler() {} /* 38:TIMER16 */
__WEAK void I2C0_EV_IRQHandler() {} /* 39:I2C0 Event */
__WEAK void I2C1_EV_IRQHandler() {} /* 40:I2C1 Event */
__WEAK void SPI0_IRQHandler() {}	/* 41:SPI0 */
__WEAK void SPI1_IRQHandler() {}	/* 42:SPI1 */
__WEAK void USART0_IRQHandler() {}	/* 43:USART0 */
__WEAK void USART1_IRQHandler() {}	/* 44:USART1 */
__WEAK void I2C0_ER_IRQHandler() {} /* 48:I2C0 Error */
__WEAK void I2C1_ER_IRQHandler() {} /* 50:I2C1 Error */

/*中断向量表 占用data 区*/
extern unsigned int _end_stack_bottom;
__attribute__((section(".vector"))) const void *__Vectors[] = {
	(void *)(&_end_stack_bottom), /*ram最大地址*/
	/*reset_handler 单片机复位后从这个地址开始运行 */
	/*cortex M只支持thumb2 指令,机器码最低位强制是1,所以地址会+1 */
	_start_func, NMI_Handler, HardFault_Handler, 0, 0, 0, 0, 0, 0, 0,
	SVC_Handler, 0, 0, PendSV_Handler, SysTick_Handler,

	WWDGT_IRQHandler /* 16:Window Watchdog Timer */
	,
	LVD_IRQHandler /* 17:LVD through EXTI Line detect */
	,
	RTC_IRQHandler /* 18:RTC through EXTI Line */
	,
	FMC_IRQHandler /* 19:FMC */
	,
	RCU_IRQHandler /* 20:RCU */
	,
	EXTI0_1_IRQHandler /* 21:EXTI Line 0 and EXTI Line 1 */
	,
	EXTI2_3_IRQHandler /* 22:EXTI Line 2 and EXTI Line 3 */
	,
	EXTI4_15_IRQHandler /* 23:EXTI Line 4 to EXTI Line 15 */
	,
	0 /* reserved                     */
	,
	DMA_Channel0_IRQHandler /* 25:DMA Channel 0 */
	,
	DMA_Channel1_2_IRQHandler /* 26:DMA Channel 1 and DMA Channel 2 */
	,
	DMA_Channel3_4_IRQHandler /* 27:DMA Channel 3 and DMA Channel 4 */
	,
	ADC_CMP_IRQHandler /* 28:ADC and Comparator */
	,
	TIMER0_BRK_UP_TRG_COM_IRQHandler /* 29:TIMER0 Break,Update,Trigger and Commutation */
	,
	TIMER0_Channel_IRQHandler /* 30:TIMER0 Channel Capture Compare */
	,
	0 /* reserved                     */
	,
	TIMER2_IRQHandler /* 32:TIMER2 */
	,
	TIMER5_IRQHandler /* 33:TIMER5 */
	,
	0 /* reserved                     */
	,
	TIMER13_IRQHandler /* 35:TIMER13 */
	,
	TIMER14_IRQHandler /* 36:TIMER14 */
	,
	TIMER15_IRQHandler /* 37:TIMER15 */
	,
	TIMER16_IRQHandler /* 38:TIMER16 */
	,
	I2C0_EV_IRQHandler /* 39:I2C0 Event */
	,
	I2C1_EV_IRQHandler /* 40:I2C1 Event */
	,
	SPI0_IRQHandler /* 41:SPI0 */
	,
	SPI1_IRQHandler /* 42:SPI1 */
	,
	USART0_IRQHandler /* 43:USART0 */
	,
	USART1_IRQHandler /* 44:USART1 */
	,
	0 /* reserved                     */
	,
	0,
	0,
	I2C0_ER_IRQHandler /* 48:I2C0 Error */
	,
	0,
	I2C1_ER_IRQHandler /* 50:I2C1 Error */
};
